package com.quectel.core.module.forum.service.impl.mongo;

import cn.hutool.core.lang.func.LambdaUtil;
import cn.hutool.core.util.DesensitizedUtil;
import com.quectel.constant.core.forum.ForumConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.constants.MongoCollectionConstants;
import com.quectel.core.module.MongoAuthComponent;
import com.quectel.core.module.forum.dto.mongo.ForumAuditRecordDto;
import com.quectel.core.module.forum.dto.mongo.ForumCommentDto;
import com.quectel.core.module.forum.dto.mongo.ForumPostDto;
import com.quectel.core.module.forum.entity.mongo.ForumAuditRecordModel;
import com.quectel.core.module.forum.service.mongo.ForumAuditRecordService;
import com.quectel.core.module.forum.service.mongo.ForumCommentService;
import com.quectel.core.module.forum.service.mongo.ForumPostService;
import com.quectel.core.module.mobileuser.dto.MobileUserDto;
import com.quectel.core.module.mobileuser.service.MobileUserService;
import com.quectel.util.common.CopyUtils;
import com.quectel.util.common.DateUtils;
import com.quectel.util.common.Request;
import com.quectel.util.kit.Snowflake;
import com.quectel.util.mongo.MongodbUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zhangheng
 * @email nolan.zhang@quectel.com
 * @date 2023/5/8 15:52
 * @description 帖子
 */
@DubboService
public class ForumAuditRecordServiceImpl implements ForumAuditRecordService {

    @Autowired
    private MongoAuthComponent mongoAuthComponent;
    @Autowired
    private MobileUserService mobileUserService;
    @Autowired
    private ForumPostService forumPostService;
    @Autowired
    private ForumCommentService forumCommentService;

    private Criteria sqlWhere(Map<String, Object> params) {
        Request request = Request.configParams(params);

        Criteria authByAllQuery = mongoAuthComponent.buildTenantConstraintsQuery(params
                , LambdaUtil.getFieldName(ForumAuditRecordModel::getTenantId)
        );

        Criteria  criteria = new Criteria();

        Long mobileUserId = request.getLong(LambdaUtil.getFieldName(ForumAuditRecordModel::getMobileUserId));
        if(mobileUserId!=null){
            criteria.and(LambdaUtil.getFieldName(ForumAuditRecordModel::getMobileUserId)).is(mobileUserId);
        }

        Byte sourceType = request.getByte(LambdaUtil.getFieldName(ForumAuditRecordModel::getSourceType));
        if(sourceType!=null){
            criteria.and(LambdaUtil.getFieldName(ForumAuditRecordModel::getSourceType)).is(sourceType);
        }

        Long sourceId = request.getLong(LambdaUtil.getFieldName(ForumAuditRecordModel::getSourceId));
        if(sourceId!=null){
            criteria.and(LambdaUtil.getFieldName(ForumAuditRecordModel::getSourceId)).is(sourceId);
        }

        Byte result = request.getByte(LambdaUtil.getFieldName(ForumAuditRecordModel::getResult));
        if(result!=null){
            criteria.and(LambdaUtil.getFieldName(ForumAuditRecordModel::getResult)).is(result);
        }

        Criteria publishTimeCriteria = new Criteria(LambdaUtil.getFieldName(ForumAuditRecordModel::getAuditTime));
        String startTime = request.getString(ForumConstants.AUDIT_TIME_SLOT_KEY_PAIR.getLeft());
        if (StringUtils.isNotBlank(startTime)) {
            publishTimeCriteria.gte(DateUtils.parse(startTime, DateUtils.FormatType.COMMON));
        }
        String endTime = request.getString(ForumConstants.AUDIT_TIME_SLOT_KEY_PAIR.getRight());
        if (StringUtils.isNotBlank(endTime)) {
            publishTimeCriteria.lte(DateUtils.parse(endTime, DateUtils.FormatType.COMMON));
        }
        if (StringUtils.isNotBlank(startTime) || StringUtils.isNotBlank(endTime)) {
            criteria.andOperator(publishTimeCriteria);
        }

        return new Criteria().andOperator(authByAllQuery,criteria);
    }

    @Override
    public ForumAuditRecordDto selectById(Long id) {
        ForumAuditRecordModel one = MongodbUtils.findOne(id, MongoCollectionConstants.FORUM_AUDIT_RECORD, ForumAuditRecordModel.class);
        return CopyUtils.copyObj(one, ForumAuditRecordDto.class);
    }

    @Override
    public List<ForumAuditRecordDto> queryList(Map<String, Object> params) {
        Request request = Request.configParams(params);
        return
                MongodbUtils.page(
                        new Query(sqlWhere(params)),
                        request.getPageNo() - 1,
                        request.getPageSize(),
                        Sort.by(Sort.Direction.DESC, SystemConstants.MONGO_ENTITY_ID_FLAG),
                        ForumAuditRecordModel.class,
                        MongoCollectionConstants.FORUM_AUDIT_RECORD
                ).stream().map(model -> {
                    ForumAuditRecordDto dto = CopyUtils.copyObj(model, ForumAuditRecordDto.class);

                    MobileUserDto mobileUserDto = mobileUserService.selectCacheById(dto.getMobileUserId());
                    if(mobileUserDto!=null){
                        dto.setNickName(mobileUserDto.getNickname());
                        dto.setMobileUserName(DesensitizedUtil.chineseName(mobileUserDto.getName()));
                        dto.setMobileUserMobile(DesensitizedUtil.mobilePhone(mobileUserDto.getMobile()));
                    }

                    if(ForumConstants.ForumAuditObjectEnum.POST.getType().equals(dto.getSourceType())){
                        ForumPostDto forumPostDto = forumPostService.selectCacheById(dto.getSourceId());
                        dto.setSourceObj(forumPostDto);
                    }

                    if(ForumConstants.ForumAuditObjectEnum.COMMENT.getType().equals(dto.getSourceType())){
                        ForumCommentDto forumCommentDto = forumCommentService.selectById(dto.getSourceId());
                        dto.setSourceObj(forumCommentDto);
                    }

                    return dto;
                }).collect(Collectors.toList());
    }

    @Override
    public int queryTotal(Map<String, Object> params) {
        return (int) MongodbUtils.count(new Query(sqlWhere(params)), MongoCollectionConstants.FORUM_AUDIT_RECORD);
    }

    @Override
    public Long save(ForumAuditRecordDto dto) {
        ForumAuditRecordModel entity = CopyUtils.copyObj(dto, ForumAuditRecordModel.class);
        entity.setId(Snowflake.nextId());
        MongodbUtils.insert(entity, MongoCollectionConstants.FORUM_AUDIT_RECORD);
        return entity.getId();
    }


    @Override
    public void deleteById(Long id) {
        MongodbUtils.delete(id, MongoCollectionConstants.FORUM_AUDIT_RECORD);
    }

    @Override
    public void deleteBatch(Long[] ids) {
        for (Long id : ids) {
            MongodbUtils.delete(id, MongoCollectionConstants.FORUM_AUDIT_RECORD);
        }
    }
}
